package com.example.databasehomework;

import android.util.Log;

import com.example.databasehomework.jsonClasses.AddCourseInfo;
import com.example.databasehomework.jsonClasses.AddExpWithoutIDInfo;
import com.example.databasehomework.jsonClasses.AddUserInfo;
import com.example.databasehomework.jsonClasses.AssignClassroomToExpInfo;
import com.example.databasehomework.jsonClasses.DelCourseOrExpInfo;
import com.example.databasehomework.jsonClasses.GetExpRequest;
import com.example.databasehomework.jsonClasses.GetStuFromExpInfo;
import com.example.databasehomework.jsonClasses.LoginInfo;
import com.example.databasehomework.jsonClasses.ModifyUserInfo;
import com.example.databasehomework.jsonClasses.StuExpRelInfoPack;
import com.example.databasehomework.jsonClasses.StudentDatabaseInfo;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class HttpUnit {
    public static final int STUDENT = 1, TEACHER = 2;
    private static String username;
    public static String name;
    public static int priority;
    //private static String BASE_URL = "http://10.135.202.165:8000/mysystem/";
    private static String BASE_URL = "http://101.43.145.90/mysystem/";

    public static Response postJson(String url, String json) throws IOException {
        OkHttpClient client = new OkHttpClient();
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Response response = client.newCall(request).execute();
        return response;
    }

    public static Response postFile(String url, String filePartName, File file) throws IOException {
        OkHttpClient client = new OkHttpClient();
        RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
        MultipartBody body = new MultipartBody.Builder().setType(MediaType.parse("multipart/form-data"))
                .addFormDataPart(filePartName, file.getName(), fileBody).build();
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Response response = client.newCall(request).execute();
        return response;
    }

    //返回是否登录成功,true表示成功
    public static UserInfo login(String username, String password) {
        LoginInfo info = new LoginInfo(username, password);
        /*OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
                .add("username",username)
                .add("password",password)
                .build();
        Request request = new Request.Builder()
                .url(BASE_URL+"login/")
                .post(body)
                .build();*/
        Gson gson = new Gson();
        String jsonStr = gson.toJson(info);
        try {
            //Response response = client.newCall(request).execute();
            Response response = postJson(BASE_URL + "login", jsonStr);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                boolean flag = jsonObject.get("status").getAsBoolean();
                if (flag) {
                    HttpUnit.username = username;
                    //HttpUnit.name = jsonObject.get("name").getAsString();
                    HttpUnit.priority = jsonObject.get("priority").getAsInt();
                    UserInfo userInfo = new UserInfo(username, jsonObject.get("email").getAsString(),
                            jsonObject.get("priority").getAsInt());
                    return userInfo;
                }
                return null;
            }
            Log.d("dbtest", "登录验证错误");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "登录验证异常");
            return null;
        }
    }
/*
    //返回是否注册成功，true表示成功,后续信息之后沟通后增加
    public static boolean register(String username, String password, String name, String sid, String sys, String email,
                                   String gender, String year, String month, String day) {
        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
                .add("username", username)
                .add("password", password)
                .add("name", name)
                .add("sid", sid)
                .add("sys", sys)
                .add("email", email)
                .add("gender", gender)
                .add("year", year)
                .add("month", month)
                .add("day", day)
                .build();
        Request request = new Request.Builder()
                .url(BASE_URL + "register/")
                .post(body)
                .build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                boolean flag = jsonObject.get("status").getAsBoolean();
                return flag;
            }
            Log.d("dbtest", "注册验证失败");
            return false;
        } catch (IOException e) {
            Log.d("dbtest", "注册验证异常");
            return false;
        }
    }
*/

    public static boolean addUser(String username, String password, int priority, String email) {
        AddUserInfo info = new AddUserInfo(username, password, priority, email, HttpUnit.username);
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            Response response = postJson(BASE_URL + "register", postJsonStr);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                return jsonObject.get("status").getAsBoolean();
            }
            Log.d("dbtest", "请求实验错误");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return false;
        }
    }

    public static UserInfo getUserInfoByUsername(String username) {
        LoginInfo info = new LoginInfo(username, null);
        Gson gson = new Gson();
        String jsonStr = gson.toJson(info);
        try {
            //Response response = client.newCall(request).execute();
            Response response = postJson(BASE_URL + "get_user_info", jsonStr);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                boolean flag = jsonObject.get("status").getAsBoolean();
                if (flag) {
                    HttpUnit.username = username;
                    //HttpUnit.name = jsonObject.get("name").getAsString();
                    HttpUnit.priority = jsonObject.get("priority").getAsInt();
                    UserInfo userInfo = new UserInfo(username, jsonObject.get("email").getAsString(),
                            jsonObject.get("priority").getAsInt());
                    return userInfo;
                }
                return null;
            }
            Log.d("dbtest", "登录验证错误");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "登录验证异常");
            return null;
        }
    }

    // 改自己的用户信息
//    返回code：
//    0：成功
//    1：自己改自己密码，旧密码错误
//    2：无权修改他人账号
//    3：被修改账号不存在
//    -1：网络错误
    public static int modifySelfInfo(String username, String password, String email, String oldPassword) {
        ModifyUserInfo info = new ModifyUserInfo(username, password, oldPassword, email, username);
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            Response response = postJson(BASE_URL + "modify_user", postJsonStr);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                return jsonObject.get("code").getAsInt();
            }
            Log.d("dbtest", "请求实验错误");
            return -1;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return -1;
        }
    }

    public static boolean addStudent(String studentID, String studentName, int sex, String dept,
                                     String phone, String email) {
        StudentDatabaseInfo info = new StudentDatabaseInfo(studentID, name, sex,
                dept, phone, email);
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            Response response = postJson(BASE_URL + "insert_stu", postJsonStr);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                return jsonObject.get("status").getAsBoolean();
            }
            Log.d("dbtest", "请求实验错误");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return false;
        }
    }

    // status: 0, 上传学生表；1，上传学生选课表
    public static boolean addStudentByXls(File xlsFile, int status) {
        try {
            String additionalUrl = "";
            if (status == 0) {
                additionalUrl = "add_stu_in_excel";
            } else if (status == 1) {
                additionalUrl = "add_stu_to_course_in_excel";
            } else {
                return false;
            }
            Response response = postFile(BASE_URL + additionalUrl, "excel_file", xlsFile);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                return jsonObject.get("status").getAsBoolean();
            }
            Log.d("dbtest", "请求实验错误");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return false;
        }
    }

    public static List<MainListItemBean> getAllCourse() {
        try {
            Response response = postJson(BASE_URL + "get_course_by_id", "{}");
            if (response.isSuccessful()) {
                String jsonStr = response.body().string();
                JsonArray jsonArray = new Gson().fromJson(jsonStr, JsonArray.class);
                int length = jsonArray.size();
                List<MainListItemBean> courseList = new ArrayList<>();
                for (int i = 0; i < length; i++) {
                    JsonObject jsonObject = (JsonObject) jsonArray.get(i);
                    MainListItemBean course = new MainListItemBean(
                            jsonObject.get("id").getAsString(),
                            jsonObject.get("name").getAsString(),
                            MainListItemBean.COURSE
                    );
                    course.setSeminar(jsonObject.get("seminar").getAsString());
                    courseList.add(course);
                }

                return courseList;
            }
            Log.d("dbtest", "请求课程错误");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求课程异常");
            return null;
        }
    }

    public static List<MainListItemBean> getExpByCourseID(String courseID) {
        GetExpRequest info = new GetExpRequest();
        if (courseID != null) {
            info.addCourseId(courseID);
        }
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            Response response = postJson(BASE_URL + "get_exp_by_id_course", postJsonStr);
            if (response.isSuccessful()) {
                String jsonStr = response.body().string();
                JsonArray jsonArray = new Gson().fromJson(jsonStr, JsonArray.class);
                int length = jsonArray.size();
                List<MainListItemBean> expList = new ArrayList<>();
                for (int i = 0; i < length; i++) {
                    JsonObject jsonObject = (JsonObject) jsonArray.get(i);
                    MainListItemBean course = new MainListItemBean(
                            jsonObject.get("id").getAsString(),
                            jsonObject.get("name").getAsString(),
                            MainListItemBean.EXPR
                    );
                    expList.add(course);
                }

                return expList;
            }
            Log.d("dbtest", "请求实验错误");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return null;
        }
    }

    public static boolean addCourse(String courseID, int year, int seminar, String name) {
        String courseFinalID = courseID + "-" + year + "-";
        String seminarStr = year + "-";
        if (seminar == 0) { // 秋季
            courseFinalID = courseFinalID + "A";
            seminarStr = seminarStr + "秋季";
        } else if (seminar == 1) { // 春季
            courseFinalID = courseFinalID + "B";
            seminarStr = seminarStr + "春季";
        } else { // 夏季
            courseFinalID = courseFinalID + "C";
            seminarStr = seminarStr + "夏季";
        }
        AddCourseInfo info = new AddCourseInfo(courseFinalID, name, seminarStr);
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            Response response = postJson(BASE_URL + "insert_course_by_request", postJsonStr);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                return jsonObject.get("status").getAsBoolean();
            }
            Log.d("dbtest", "请求实验错误");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return false;
        }
    }

    public static boolean addExperiment(String name, String courseID, List<String> classrooms) {
        AddExpWithoutIDInfo info = new AddExpWithoutIDInfo(name, courseID);
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            Response response = postJson(BASE_URL + "insert_exp_without_id", postJsonStr);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                boolean flag = jsonObject.get("status").getAsBoolean();
                if (!flag) {
                    return false;
                }
                String expId = jsonObject.get("exp_id").getAsString();
                flag = assignClassroomsToExp(expId, classrooms);
                return flag;
            }
            Log.d("dbtest", "请求实验错误");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return false;
        }
    }

    public static boolean delCourseOrExp(String delID, int courseOrExp) { // 0:删除课程；1：删除实验
        DelCourseOrExpInfo info = new DelCourseOrExpInfo();
        info.addDelID(delID);
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            String subUrl;
            if (courseOrExp == 0) {
                subUrl = "del_course_by_id";
            } else {
                subUrl = "del_exp_by_id";
            }
            Response response = postJson(BASE_URL + subUrl, postJsonStr);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                return jsonObject.get("status").getAsBoolean();
            }
            Log.d("dbtest", "请求实验错误");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return false;
        }
    }

    public static List<DetailListBean> getStudentFromExp(String expID, String classroomID) {
        GetStuFromExpInfo info = new GetStuFromExpInfo();
        info.addExp(expID);
        info.addRoom(classroomID);
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            String subUrl = "get_stu_exp_rel";
            Response response = postJson(BASE_URL + subUrl, postJsonStr);
            if (response.isSuccessful()) {
                ArrayList<DetailListBean> studentList = new ArrayList<>();
                String jsonStr = response.body().string();
                JsonArray jsonArray = new Gson().fromJson(jsonStr, JsonArray.class);
                int length = jsonArray.size();
                for (int i = 0; i < length; i++) {
                    JsonObject jsonObject = (JsonObject) jsonArray.get(i);
                    DetailListBean stu = new DetailListBean(
                            jsonObject.get("student_id").getAsString(),
                            jsonObject.get("student_name").getAsString(),
                            jsonObject.get("seat_id").getAsInt(),
                            jsonObject.get("sign_in").getAsBoolean()
                    );
                    studentList.add(stu);
                }
                return studentList;
            }
            Log.d("dbtest", "请求实验错误");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return null;
        }
    }

    public static StudentInfo getStudentExpInfo(String expID, String studentID) { // 获取单个学生某实验信息
        GetStuFromExpInfo info = new GetStuFromExpInfo();
        info.addExp(expID);
        info.addStudent(studentID);
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            String subUrl = "get_stu_exp_rel";
            Response response = postJson(BASE_URL + subUrl, postJsonStr);
            if (response.isSuccessful()) {
                String jsonStr = response.body().string();
                JsonArray jsonArray = new Gson().fromJson(jsonStr, JsonArray.class);
                int length = jsonArray.size();
                StudentInfo stu = null;
                for (int i = 0; i < length; i++) {
                    JsonObject jsonObject = (JsonObject) jsonArray.get(i);
                    stu = new StudentInfo(
                            jsonObject.get("sign_in").getAsBoolean(),
                            jsonObject.get("sign_out").getAsBoolean(),
                            jsonObject.get("pass_num").getAsInt(),
                            jsonObject.get("answer").getAsInt(),
                            jsonObject.get("other_info").getAsString()
                    );
                }
                return stu;
            }
            Log.d("dbtest", "请求实验错误");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return null;
        }
    }

    public static boolean modifyStudentExpAllInfo(String expID, String studentID,
                                                  StudentInfo information) { // 修改单个学生某实验信息
        StuExpRelInfoPack info = new StuExpRelInfoPack(studentID, expID, information);
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            String subUrl = "modify_stu_exp_rel";
            Response response = postJson(BASE_URL + subUrl, postJsonStr);
            if (response.isSuccessful()) {
                String jsonStr = response.body().string();
                JsonObject jsonObject = new Gson().fromJson(jsonStr, JsonObject.class);
                return jsonObject.get("status").getAsBoolean();
            }
            Log.d("dbtest", "请求实验错误");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return false;
        }
    }

    public static boolean modifyStudentExpSignInInfo(String expID, String studentID,
                                                     boolean SignIn) { // 修改单个学生某实验签到信息
        String postJsonStr = "{\"exp_id\":\"" + expID + "\"," +
                "\"student_id\":\"" + studentID + "\"," +
                "\"sign_in\":" + SignIn + "}";
        try {
            String subUrl = "modify_stu_exp_rel";
            Response response = postJson(BASE_URL + subUrl, postJsonStr);
            if (response.isSuccessful()) {
                String jsonStr = response.body().string();
                JsonObject jsonObject = new Gson().fromJson(jsonStr, JsonObject.class);
                return jsonObject.get("status").getAsBoolean();
            }
            Log.d("dbtest", "请求实验错误");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return false;
        }
    }

    public static List<DetailListBean> getStudentWaitingList(String classroom, String expID) {
        String postJsonStr = "{\"classroom_id\":\"" + classroom + "\",\"exp_id\":\"" + expID + "\"}";
        try {
            String subUrl = "get_room_wait_list";
            Response response = postJson(BASE_URL + subUrl, postJsonStr);
            if (response.isSuccessful()) {
                String jsonStr = response.body().string();
                JsonObject jsonObject = new Gson().fromJson(jsonStr, JsonObject.class);
                JsonArray waitlistJsonArr = jsonObject.get("queue").getAsJsonArray();
                ArrayList<DetailListBean> waitlist = new ArrayList<>();
                int length = waitlistJsonArr.size();
                for (int i = 0; i < length; i++) {
                    JsonObject stuJsonObject = (JsonObject) waitlistJsonArr.get(i);
                    DetailListBean stuInfo = new DetailListBean(
                            stuJsonObject.get("student_id").getAsString(),
                            stuJsonObject.get("student_name").getAsString(),
                            stuJsonObject.get("seat_id").getAsInt(),
                            stuJsonObject.get("sign_in").getAsBoolean()
                    );
                    waitlist.add(stuInfo);
                }
                return waitlist;
            }
            Log.d("dbtest", "请求实验错误");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return null;
        }
    }

    public static boolean addClassroom(String classRoomID, int roomSize) {
        String postJsonStr = "{\"id\":\"" + classRoomID + "\"," +
                "\"size\":" + roomSize + "}";
        try {
            Response response = postJson(BASE_URL + "insert_classroom", postJsonStr);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                return jsonObject.get("status").getAsBoolean();
            }
            Log.d("dbtest", "请求实验错误");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return false;
        }
    }

    public static List<String> getAllClassrooms() {
        String postJsonStr = "{}";
        try {
            String subUrl = "get_classroom_by_id";
            Response response = postJson(BASE_URL + subUrl, postJsonStr);
            if (response.isSuccessful()) {
                ArrayList<String> roomList = new ArrayList<>();
                String jsonStr = response.body().string();
                JsonArray jsonArray = new Gson().fromJson(jsonStr, JsonArray.class);
                int length = jsonArray.size();
                for (int i = 0; i < length; i++) {
                    JsonObject jsonObject = (JsonObject) jsonArray.get(i);
                    roomList.add(jsonObject.get("id").getAsString());
                }
                return roomList;
            }
            Log.d("dbtest", "请求实验错误");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return null;
        }
    }

    public static boolean assignClassroomsToExp(String expID, List<String> classrooms) {
        AssignClassroomToExpInfo info = new AssignClassroomToExpInfo(expID, classrooms);
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            String subUrl = "insert_exp_and_classroom";
            Response response = postJson(BASE_URL + subUrl, postJsonStr);
            if (response.isSuccessful()) {
                JsonObject jsonObject = new Gson().fromJson(response.body().string(), JsonObject.class);
                return jsonObject.get("status").getAsBoolean();
            }
            Log.d("dbtest", "请求实验错误");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return false;
        }
    }

    public static List<String> getClassroomsFromExp(String expID) {
        GetStuFromExpInfo info = new GetStuFromExpInfo();
        if (expID != null) {
            info.addExp(expID);
        }
        Gson gson = new Gson();
        String postJsonStr = gson.toJson(info);
        try {
            String subUrl = "get_exp_and_classroom";
            Response response = postJson(BASE_URL + subUrl, postJsonStr);
            if (response.isSuccessful()) {
                ArrayList<String> roomList = new ArrayList<>();
                String jsonStr = response.body().string();
                JsonArray jsonArray = new Gson().fromJson(jsonStr, JsonArray.class);
                int length = jsonArray.size();
                for (int i = 0; i < length; i++) {
                    JsonObject jsonObject = (JsonObject) jsonArray.get(i);
                    roomList.add(jsonObject.get("room_id").getAsString());
                }
                return roomList;
            }
            Log.d("dbtest", "请求实验错误");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("dbtest", "请求实验异常");
            return null;
        }
    }
}